<?php
/**
 * The Acl resource load authorizations and denials of access to URLs, according to user's groups.
 * It is very likely that each project manages its access auth differently,
 * and since management must be done at the application level, this class Acl is left in the skeleton
 * as an example for developers.
 *
 * Format of Acl :
 * <code>
 * [roleA]
 * /controller # comment
 * /controller/action
 * !/denied/page
 *
 * [roleB]
 * /controller # comment
 * module:/controller/action
 * </code>
 */
class Application_Resource_Acl extends Zend_Application_Resource_ResourceAbstract
{
    /**
     * Load and parse the Acl file defined in resource.acl.acl_path (usually application/configs/acl.ini)
     * @return array
     */
    public function init()
    {
        $this->getBootstrap()->bootstrap('cache');
        $cache = $this->getBootstrap()->getResource('cache');
        if (! $acl = $cache->load('acl')) {
            $options = $this->getOptions();
            $acl = $this->_parseAclString(file_get_contents($options['acl_path']));
            $cache->save($acl, 'acl');
        }

        return $acl;
    }

    /**
     * Parse Acl
     * @param string $acl
     * @return array
     */

    protected function _parseAclString($acl)
    {
        $lines  = explode("\n", $acl);
        $result = array();
        $role = 'public';

        foreach ($lines as $line) {
            $line = preg_replace('/(#|;).*/', '', $line); // Remove comments
            $line = trim($line);

            if (empty($line))
                continue;

            $allowed = true;

            if ($line[0] == "[" && $endIdx = strpos($line, "]")) {
                $role = trim(substr($line, 1, $endIdx - 1));
                continue;
            }

            if ('!' === $line[0]) {
                $allowed = false;
                $line = substr($line, 1);
            }

            if (false === strpos($line, ":")) {
                $line = 'default:' . $line;
            }

            $result[$role][$line] = $allowed;
        }
        return $result;
    }
}